import 'package:bitcoin_mine/model/contract.dart';
import 'package:bitcoin_mine/model/register_model.dart';
import 'package:json_annotation/json_annotation.dart';

@JsonSerializable()
class MineInfo {
  List<Good> goods;
  Goods_map goods_map;
  Contract? free_contract;
  User_info? user_info;
  User user;
  List<Contract> contracts;
  int? contract_count;
  double? total_hashrate;
  Exchange_rate exchange_rate;
  Bitcoin_history bitcoin_history;
  Withdraw_links withdraw_links;
  Withdraw_rule withdraw_rule;

  MineInfo({
    required this.goods,
    required this.goods_map,
    this.free_contract,
    this.user_info,
    required this.user,
    required this.contracts,
    this.contract_count,
    required this.total_hashrate,
    required this.exchange_rate,
    required this.bitcoin_history,
    required this.withdraw_links,
    required this.withdraw_rule,
  });

  factory MineInfo.fromJson(Map<String, dynamic> json) {
    return MineInfo(
      goods: (json['goods'] as List).map((e) => Good.fromJson(e)).toList(),
      goods_map: Goods_map.fromJson(json['goods_map']),
      free_contract:
          json['free_contract'] != null
              ? Contract.fromJson(json['free_contract'])
              : null,
      user_info:
          json['user_info'] != null
              ? User_info.fromJson(json['user_info'])
              : null,
      user: User.fromJson(json['user']),
      contracts:
          (json['contracts'] as List).map((e) => Contract.fromJson(e)).toList(),
      contract_count: json['contract_count'] as int?,
      total_hashrate: json['total_hashrate'].toDouble(),
      exchange_rate: Exchange_rate.fromJson(json['exchange_rate']),
      bitcoin_history: Bitcoin_history.fromJson(json['bitcoin_history']),
      withdraw_links: Withdraw_links.fromJson(json['withdraw_links']),
      withdraw_rule: Withdraw_rule.fromJson(json['withdraw_rule']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'goods': goods.map((e) => e.toJson()).toList(),
      'goods_map': goods_map.toJson(),
      'free_contract': free_contract?.toJson(),
      'user_info': user_info?.toJson(),
      'user': user.toJson(),
      'contracts': contracts.map((e) => e.toJson()).toList(),
      'contract_count': contract_count,
      'total_hashrate': total_hashrate,
      'exchange_rate': exchange_rate.toJson(),
      'bitcoin_history': bitcoin_history.toJson(),
      'withdraw_links': withdraw_links.toJson(),
      'withdraw_rule': withdraw_rule.toJson(),
    };
  }
}

class Good {
  int id;
  int app_id;
  String product_id;
  String name;
  //1: weekly, 2: monthly, 3: season, 4: yearly
  int circle;
  int level;
  double price;
  String? discount_price;
  String? original_price;
  double hashrate;
  String promotional;
  int status;
  String created_at;
  String updated_at;

  Good({
    required this.id,
    required this.app_id,
    required this.product_id,
    required this.name,
    required this.circle,
    required this.level,
    required this.price,
    this.discount_price,
    this.original_price,
    required this.hashrate,
    required this.promotional,
    required this.status,
    required this.created_at,
    required this.updated_at,
  });

  factory Good.fromJson(Map<String, dynamic> json) {
    return Good(
      id: json['id'],
      app_id: json['app_id'],
      product_id: json['product_id'],
      name: json['name'],
      circle: json['circle'],
      level: json['level'],
      price: json['price'],
      discount_price: json['discount_price']?.toDouble(),
      original_price: json['original_price']?.toDouble(),
      hashrate: json['hashrate'],
      promotional: json['promotional'],
      status: json['status'],
      created_at: json['created_at'],
      updated_at: json['updated_at'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'app_id': app_id,
      'product_id': product_id,
      'name': name,
      'circle': circle,
      'level': level,
      'price': price,
      'discount_price': discount_price,
      'original_price': original_price,
      'hashrate': hashrate,
      'promotional': promotional,
      'status': status,
      'created_at': created_at,
      'updated_at': updated_at,
    };
  }
}

class Goods_map {
  @JsonKey(name: '1')
  List<Good> group1;
  @JsonKey(name: '2')
  List<Good> group2;
  @JsonKey(name: '3')
  List<Good> group3;
  @JsonKey(name: '4')
  List<Good> group4;
  // @JsonKey(name: '5')
  // List<Good> group5;

  Goods_map({
    required this.group1,
    required this.group2,
    required this.group3,
    required this.group4,
    // required this.group5,
  });

  factory Goods_map.fromJson(Map<String, dynamic> json) {
    return Goods_map(
      group1: (json['1'] as List).map((e) => Good.fromJson(e)).toList(),
      group2: (json['2'] as List).map((e) => Good.fromJson(e)).toList(),
      group3: (json['3'] as List).map((e) => Good.fromJson(e)).toList(),
      group4: (json['4'] as List).map((e) => Good.fromJson(e)).toList(),
      // group5: (json['5'] as List).map((e) => Good.fromJson(e)).toList(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      '1': group1.map((e) => e.toJson()).toList(),
      '2': group2.map((e) => e.toJson()).toList(),
      '3': group3.map((e) => e.toJson()).toList(),
      '4': group4.map((e) => e.toJson()).toList(),
      // '5': group5.map((e) => e.toJson()).toList(),
    };
  }
}

class User_info {
  int id;
  int app_id;
  int user_id;
  String? parent_user_id;
  String? invitation_code;
  double balance;
  double? hashrate;
  double? proxy_1_balance;
  double? proxy_2_balance;
  double? proxy_3_balance;
  int? goods_id;
  String vip_level;
  String? vip_started_at;
  String? vip_ended_at;
  int status;
  String created_at;
  String updated_at;

  User_info({
    required this.id,
    required this.app_id,
    required this.user_id,
    this.parent_user_id,
    this.invitation_code,
    required this.balance,
    this.hashrate,
    this.proxy_1_balance,
    this.proxy_2_balance,
    this.proxy_3_balance,
    this.goods_id,
    required this.vip_level,
    this.vip_started_at,
    this.vip_ended_at,
    required this.status,
    required this.created_at,
    required this.updated_at,
  });

  factory User_info.fromJson(Map<String, dynamic> json) {
    // print('user_info: $json');
    return User_info(
      id: json['id'],
      app_id: json['app_id'],
      user_id: json['user_id'],
      parent_user_id: json['parent_user_id'],
      invitation_code: json['invitation_code'] as String?,
      balance: json['balance'].toDouble(),
      hashrate: json['hashrate'] as double?,
      proxy_1_balance: json['proxy_1_balance'] as double?,
      proxy_2_balance: json['proxy_2_balance'] as double?,
      proxy_3_balance: json['proxy_3_balance'] as double?,
      goods_id: json['goods_id'] as int?,
      vip_level: json['vip_level'],
      vip_started_at: json['vip_started_at'] as String?,
      vip_ended_at: json['vip_ended_at'] as String?,
      status: json['status'],
      created_at: json['created_at'],
      updated_at: json['updated_at'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'app_id': app_id,
      'user_id': user_id,
      'parent_user_id': parent_user_id,
      'invitation_code': invitation_code,
      'balance': balance,
      'hashrate': hashrate?.toString(),
      'proxy_1_balance': proxy_1_balance?.toString(),
      'proxy_2_balance': proxy_2_balance?.toString(),
      'proxy_3_balance': proxy_3_balance?.toString(),
      'goods_id': goods_id,
      'vip_level': vip_level,
      'vip_started_at': vip_started_at,
      'vip_ended_at': vip_ended_at,
      'status': status,
      'created_at': created_at,
      'updated_at': updated_at,
    };
  }
}

class Exchange_rate {
  String value;
  String basePair;
  int timestamp;
  String source;
  String symbol;

  Exchange_rate({
    required this.value,
    required this.basePair,
    required this.timestamp,
    required this.source,
    required this.symbol,
  });

  factory Exchange_rate.fromJson(Map<String, dynamic> json) {
    return Exchange_rate(
      value: json['value'],
      basePair: json['basePair'],
      timestamp: json['timestamp'],
      source: json['source'],
      symbol: json['symbol'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'value': value,
      'basePair': basePair,
      'timestamp': timestamp,
      'source': source,
      'symbol': symbol,
    };
  }
}

class Bitcoin_history {
  int timestamp;
  List<Data> data;

  Bitcoin_history({required this.timestamp, required this.data});

  factory Bitcoin_history.fromJson(Map<String, dynamic> json) {
    return Bitcoin_history(
      timestamp: json['timestamp'],
      data: (json['data'] as List).map((e) => Data.fromJson(e)).toList(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'timestamp': timestamp,
      'data': data.map((e) => e.toJson()).toList(),
    };
  }
}

class Withdraw_links {
  String lightning;
  String onchain;

  Withdraw_links({required this.lightning, required this.onchain});

  factory Withdraw_links.fromJson(Map<String, dynamic> json) {
    return Withdraw_links(
      lightning: json['lightning'],
      onchain: json['onchain'],
    );
  }

  Map<String, dynamic> toJson() {
    return {'lightning': lightning, 'onchain': onchain};
  }
}

class Data {
  int circulatingSupply;
  String priceUsd;
  int time;
  String date;

  Data({
    required this.circulatingSupply,
    required this.priceUsd,
    required this.time,
    required this.date,
  });

  factory Data.fromJson(Map<String, dynamic> json) {
    return Data(
      circulatingSupply: json['circulatingSupply'],
      priceUsd: json['priceUsd'],
      time: json['time'],
      date: json['date'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'circulatingSupply': circulatingSupply,
      'priceUsd': priceUsd,
      'time': time,
      'date': date,
    };
  }
}

class Withdraw_rule {
  @JsonKey(name: 'min')
  double min_withdrawal;
  @JsonKey(name: 'max')
  double max_withdrawal;
  @JsonKey(name: 'fee')
  double withdrawal_fee;

  Withdraw_rule({
    required this.min_withdrawal,
    required this.max_withdrawal,
    required this.withdrawal_fee,
  });

  factory Withdraw_rule.fromJson(Map<String, dynamic> json) {
    return Withdraw_rule(
      min_withdrawal: json['min'],
      max_withdrawal: json['max'],
      withdrawal_fee: json['fee'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'min': min_withdrawal,
      'max': max_withdrawal,
      'fee': withdrawal_fee,
    };
  }
}
